home *** CD-ROM | disk | FTP | other *** search
- .386
- .model flat
- .stack 1000h
- .code
-
- lowmemptr dd ?
- lowmemseg dw ?
- linearadr dd ?
- videomem dd ?
- wgran dd ?
- vscreen dd ?
-
- text_success db 'Success.',13,10,36
- text_vbe_error db 'VESA error.',13,10,36
- text_no_mode db 'The requested video mode is unsupported!',13,10,36
- text_no_memory db 'There is insufficient memory available!',13,10,36
-
- _ label
- _edi label dword
- _di label word
- _dih db ?
- _dil db ?
- _edih db ?
- _edil db ?
- _esi label dword
- _si label word
- _sih db ?
- _sil db ?
- _esih db ?
- _esil db ?
- _ebp label dword
- _bp label word
- _bph db ?
- _bpl db ?
- _ebph db ?
- _ebpl db ?
- _reserv dd ?
- _ebx label dword
- _bx label word
- _bh db ?
- _bl db ?
- _ebh db ?
- _ebl db ?
- _edx label dword
- _dx label word
- _dh db ?
- _dl db ?
- _edh db ?
- _edl db ?
- _ecx label dword
- _cx label word
- _ch db ?
- _cl db ?
- _ech db ?
- _ecl db ?
- _eax label dword
- _ax label word
- _ah db ?
- _al db ?
- _eah db ?
- _eal db ?
- _flags dw ?
- _es dw ?
- _ds dw ?
- _fs dw ?
- _gs dw ?
- _ip dw ?
- _cs dw ?
- _sp dw ?
- _ss dw 0
-
-
- main:
- ;1. Check if the videomode we want is supported on the computer.
- mov eax,0ee02h
- int 31h
- mov lowmemseg,ax
- mov linearadr,ebx
- push ax ;\
- xor eax,eax ; > Clears the high bits of eax
- pop ax ;/
- shl eax,4 ; Makes eax the absolute address of the RM seg
- sub eax,ebx ; Makes eax a near pointer to the RM segment
- mov lowmemptr,eax
- mov eax,0a0000h
- sub eax,ebx
- mov videomem,eax
-
- mov ax,lowmemseg
- mov _es,ax
- mov _di,0
- mov _ax,4f00h
- mov eax,300h
- mov ebx,10h
- xor ecx,ecx
- lea edi,_ ;our RM callback structure
- int 31h
-
- cmp _ax,4fh
- jne vbe_error
- xor eax,eax
- xor ebx,ebx
- mov ax,word ptr lowmemptr[0eh]
- mov bx,word ptr lowmemptr[10h]
- shl ebx,4
- add eax,ebx
- sub eax,linearadr
- mov esi,eax
- mov bx,101h ;desired video mode
- loop1:
- lodsw
- cmp ax,-1
- je mode_not_supported
- cmp ax,bx
- jne loop1
-
- ;2. We need the window granularity of this mode to do proper bankswitching.
- mov ax,lowmemseg
- mov _es,ax
- mov _di,0
- mov _ax,4f01h
- mov _cx,101h ;video mode
- mov eax,300h
- mov ebx,10h
- xor ecx,ecx
- lea edi,_ ;our RM callback structure
- int 31h
-
- cmp _ax,4fh
- jne vbe_error
- xor ebx,ebx
- mov bx,word ptr lowmemptr[4]
- shl ebx,10
- mov wgran,ebx
-
- ;3. Allocate memory for our virtual screen and switch to the SVGA mode.
- mov eax,0ee42h
- mov edx,640*480
- int 31h
- jc not_enough_memory
- mov vscreen,edx
-
- mov eax,4f02h
- mov ebx,101h ;our video mode..
- int 10h
-
- ;4. Put something on the virtual screen.
- mov edi,vscreen
- xor eax,eax
- mov ebx,480
- drawloop1:
- mov ecx,640/4
- rep stosd
- drawlabel1:
- inc eax
- or eax,eax
- jz drawlabel1
- add eax,01010100h
- dec ebx
- jnz drawloop1
-
- ;5. Flip the virtual screen out to video memory.
- call flip
-
- ;Wait for keypress, then switch to textmode, and exit to DOS.
- xor eax,eax
- int 16h
- mov eax,3
- int 10h
- lea edx,text_success
- exit:
- mov ah,9
- int 21h
- mov eax,4c00h
- int 21h
-
- vbe_error:
- lea edx,text_vbe_error
- jmp exit
-
- mode_not_supported:
- lea edx,text_no_mode
- jmp exit
-
- not_enough_memory:
- lea edx,text_no_memory
- jmp exit
-
- flip proc
- push eax ebx ecx edx esi edi ebp
- xor dx,dx ;bank counter
- xor ebx,ebx ;used to clear the buffer
- mov ebp,640*480 ;bytes left to move-counter
- mov esi,vscreen
- mov edi,videomem
-
- outer_loop:
- call setbank
- cmp ebp,65536
- jae mov64k
- mov ecx,ebp
- sub ebp,ecx ;update counter
- shr ecx,2 ;divide by 4 to get number of dwords to move
- jmp loop_start
- mov64k: sub ebp,65536
- mov ecx,16384
- loop_start:
- mov eax,[esi] ;read a dword from the buffer
- mov [edi],eax ;and write it to video mem
- mov [esi],ebx ;clear the dword in the buffer
- add esi,4 ;update pointers
- add edi,4 ;update pointers
- dec ecx
- jnz loop_start ;loop for 16384 times, this will move 65536 bytes..
- inc edx ;increase bank counter
- sub edi,65536
- cmp ebp,3 ;check if we have more than 3 bytes left,
- ja outer_loop ;if so then jump up
- or ebp,ebp ;are we completely done?
- jz flpbye ;yes, then quit..
-
- mov ecx,ebp ;otherwise, move these bytes to video mem
- loop2_start: ;this loop is used to move the bytes left
- mov al,[esi] ;read one byte from buffer
- mov [edi],al ;and write to video mem
- mov [esi],bl ;clear buffer
- inc esi ;increase source pointer
- inc edi ;increase destination pointer
- dec ecx
- jnz loop2_start ;play it again, Sam!
- flpbye: pop ebp edi esi edx ecx ebx eax
- retn
- flip endp
-
- setbank proc
- push ax bx dx
- mov ax,4f05h
- xor bx,bx
- int 10h
- pop dx bx ax
- retn
- setbank endp
-
- end main
-